//
// Created by richa on 2019/11/16.
//

#include "HeatStoreSimTemperatureSensor.h"
#include <iostream>
#include <unistd.h>

using namespace std;

HeatStoreSimTemperatureSensor::HeatStoreSimTemperatureSensor(uint16_t *outputExchangerAddr, uint16_t *outputWaterAddr,
                                                             uint8_t *pumpFlag) : output_exchanger_addr(
        outputExchangerAddr), output_water_addr(outputWaterAddr), pumpFlag(pumpFlag) {
    this->initIlluminationInputThread();
    this->initOutputToAddrThread();
}

void HeatStoreSimTemperatureSensor::initIlluminationInputThread() {
    this->illuminationInputThread = thread([](HeatStoreSimTemperatureSensor * p)->void{
        int i;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-noreturn"
        for(;;){
            cout<< "请输入光照强度: " << endl;
            cin >> i;
            if(i<= 1000 && i>= 0){
                p->setIllumination(i);
            }
        }
#pragma clang diagnostic pop
    }, this);
}

void HeatStoreSimTemperatureSensor::setIllumination(int i) {
    HeatStoreSimTemperatureSensor::illumination = i;
}

void HeatStoreSimTemperatureSensor::initOutputToAddrThread() {
    this->outputToAddrThread  = thread([](HeatStoreSimTemperatureSensor * p)->void{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-noreturn"
        for(;;){
            sleep(1);
            bool pump = (p->pumpFlag != nullptr) ? ((*p->pumpFlag) != 0) : false;
            uint16_t diff = 0;
            // logic--------------------------------------
            // ----water----------------------------------
            if(!pump){
                p->waterTemperatureSensor.pause();
                p->waterTemperatureSensor.setBackgroundStep(0);
            }else{
                p->waterTemperatureSensor.setBackgroundTarget(p->exchangerTemperatureSensor.get(), 40);
            }
            // ----exchanger------------------------------
            if( !pump){
                p->exchangerTemperatureSensor.setBackgroundTarget(p->illumination, 40);
            }else{
                int step = 0;
                if(p->exchangerTemperatureSensor.get() < p->illumination){
                    step = (p->illumination - p->exchangerTemperatureSensor.get()) / 100 + 1;
                }else if( p->exchangerTemperatureSensor.get() > p->illumination){
                    step = - ((p->exchangerTemperatureSensor.get() - p->illumination) / 100 + 1);

                    if(p->exchangerTemperatureSensor.get() < p->waterTemperatureSensor.get()){
                        step = step + (p->waterTemperatureSensor.get() - p->exchangerTemperatureSensor.get()) / 40 + 2;
                    }else if(p->exchangerTemperatureSensor.get() > p->waterTemperatureSensor.get()){
                        step = step - ( p->exchangerTemperatureSensor.get() - p->waterTemperatureSensor.get()) / 40 - 2;
                    }
                }else{
                    step = 0;
                }


                p->exchangerTemperatureSensor.setBackgroundStep(step);
            }

            // output-------------------------------------
            if(p->output_exchanger_addr != nullptr){
                *(p->output_exchanger_addr) = p->exchangerTemperatureSensor.get();
            }
            if(p->output_water_addr != nullptr){
                *(p->output_water_addr) = p->waterTemperatureSensor.get();
            }
//            cout<<"water:"<<p->waterTemperatureSensor.get()<<",  exchanger:"<<p->exchangerTemperatureSensor.get()<<endl;
        }
#pragma clang diagnostic pop
    }, this);
}


